home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / idlelib / CodeContext.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2005-10-18  |  6KB  |  152 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.4)
  3.  
  4. """CodeContext - Display the block context of code at top of edit window
  5.  
  6. Once code has scrolled off the top of the screen, it can be difficult
  7. to determine which block you are in.  This extension implements a pane
  8. at the top of each IDLE edit window which provides block structure
  9. hints.  These hints are the lines which contain the block opening
  10. keywords, e.g. 'if', for the enclosing block.  The number of hint lines
  11. is determined by the numlines variable in the CodeContext section of
  12. config-extensions.def. Lines which do not open blocks are not shown in
  13. the context hints pane.
  14.  
  15. """
  16. import Tkinter
  17. from configHandler import idleConf
  18. from sets import Set
  19. import re
  20. BLOCKOPENERS = Set([
  21.     'class',
  22.     'def',
  23.     'elif',
  24.     'else',
  25.     'except',
  26.     'finally',
  27.     'for',
  28.     'if',
  29.     'try',
  30.     'while'])
  31. INFINITY = 1 << 30
  32. UPDATEINTERVAL = 100
  33. FONTUPDATEINTERVAL = 1000
  34.  
  35. getspacesfirstword = lambda s, c = re.compile('^(\\s*)(\\w*)'): c.match(s).groups()
  36.  
  37. class CodeContext:
  38.     menudefs = [
  39.         ('options', [
  40.             ('!Code Conte_xt', '<<toggle-code-context>>')])]
  41.     numlines = idleConf.GetOption('extensions', 'CodeContext', 'numlines', type = 'int', default = 3)
  42.     bgcolor = idleConf.GetOption('extensions', 'CodeContext', 'bgcolor', type = 'str', default = 'LightGray')
  43.     fgcolor = idleConf.GetOption('extensions', 'CodeContext', 'fgcolor', type = 'str', default = 'Black')
  44.     
  45.     def __init__(self, editwin):
  46.         self.editwin = editwin
  47.         self.text = editwin.text
  48.         self.textfont = self.text['font']
  49.         self.label = None
  50.         self.info = list(self.interesting_lines(1))
  51.         self.lastfirstline = 1
  52.         visible = idleConf.GetOption('extensions', 'CodeContext', 'visible', type = 'bool', default = False)
  53.         if visible:
  54.             self.toggle_code_context_event()
  55.             self.editwin.setvar('<<toggle-code-context>>', True)
  56.         
  57.         self.text.after(UPDATEINTERVAL, self.timer_event)
  58.         self.text.after(FONTUPDATEINTERVAL, self.font_timer_event)
  59.  
  60.     
  61.     def toggle_code_context_event(self, event = None):
  62.         if not self.label:
  63.             self.label = Tkinter.Label(self.editwin.top, text = '\n' * (self.numlines - 1), anchor = 'w', justify = 'left', font = self.textfont, bg = self.bgcolor, fg = self.fgcolor, relief = 'sunken', width = 1)
  64.             self.label.pack(side = 'top', fill = 'x', expand = 0, after = self.editwin.status_bar)
  65.         else:
  66.             self.label.destroy()
  67.             self.label = None
  68.         idleConf.SetOption('extensions', 'CodeContext', 'visible', str(self.label is not None))
  69.         idleConf.SaveUserCfgFiles()
  70.  
  71.     
  72.     def get_line_info(self, linenum):
  73.         '''Get the line indent value, text, and any block start keyword
  74.  
  75.         If the line does not start a block, the keyword value is False.
  76.         The indentation of empty lines (or comment lines) is INFINITY.
  77.         There is a dummy block start, with indentation -1 and text "".
  78.  
  79.         Return the indent level, text (including leading whitespace),
  80.         and the block opening keyword.
  81.  
  82.         '''
  83.         if linenum == 0:
  84.             return (-1, '', True)
  85.         
  86.         text = self.text.get('%d.0' % linenum, '%d.end' % linenum)
  87.         (spaces, firstword) = getspacesfirstword(text)
  88.         if firstword in BLOCKOPENERS:
  89.             pass
  90.         opener = firstword
  91.         if len(text) == len(spaces) or text[len(spaces)] == '#':
  92.             indent = INFINITY
  93.         else:
  94.             indent = len(spaces)
  95.         return (indent, text, opener)
  96.  
  97.     
  98.     def interesting_lines(self, firstline):
  99.         '''Generator which yields context lines, starting at firstline.'''
  100.         lastindent = INFINITY
  101.         for line_index in xrange(firstline, -1, -1):
  102.             (indent, text, opener) = self.get_line_info(line_index)
  103.             if indent < lastindent:
  104.                 lastindent = indent
  105.                 if opener in ('else', 'elif'):
  106.                     lastindent += 1
  107.                 
  108.                 if opener and line_index < firstline:
  109.                     yield (line_index, text)
  110.                 
  111.             line_index < firstline
  112.         
  113.  
  114.     
  115.     def update_label(self):
  116.         firstline = int(self.text.index('@0,0').split('.')[0])
  117.         if self.lastfirstline == firstline:
  118.             return None
  119.         
  120.         self.lastfirstline = firstline
  121.         tmpstack = []
  122.         for line_index, text in self.interesting_lines(firstline):
  123.             while self.info[-1][0] > line_index:
  124.                 del self.info[-1]
  125.             if self.info[-1][0] == line_index:
  126.                 break
  127.             
  128.             tmpstack.append((line_index, text))
  129.         
  130.         while tmpstack:
  131.             self.info.append(tmpstack.pop())
  132.         lines = [] + [ x[1] for x in self.info[-(self.numlines):] ]
  133.         self.label['text'] = '\n'.join(lines)
  134.  
  135.     
  136.     def timer_event(self):
  137.         if self.label:
  138.             self.update_label()
  139.         
  140.         self.text.after(UPDATEINTERVAL, self.timer_event)
  141.  
  142.     
  143.     def font_timer_event(self):
  144.         newtextfont = self.text['font']
  145.         if self.label and newtextfont != self.textfont:
  146.             self.textfont = newtextfont
  147.             self.label['font'] = self.textfont
  148.         
  149.         self.text.after(FONTUPDATEINTERVAL, self.font_timer_event)
  150.  
  151.  
  152.